package cn.good.yan.config.demo3;

import cn.good.yan.model.entity.User;
import cn.good.yan.model.mapper.UserMapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsPasswordService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.provisioning.UserDetailsManager;

import java.util.ArrayList;
import java.util.Collection;

/**
 * 三
 * 2. 用户认证 - 前后端分离
 * 【基于数据库的用户认证】
 * 授权： 有给该用户，进行赋值，权限列表
 *
 * @author shengren.yan
 * @create 2024-07-17
 */
@Configuration
public class DBUserDetailsManager implements UserDetailsManager, UserDetailsPasswordService {

    @Resource
    private UserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // sql - 查询用户表
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        User user = userMapper.selectOne(queryWrapper);
        // 该用户为null
        if (user == null) {
            throw new UsernameNotFoundException(username);
        } else {

            // 1.用户权限资源的配置
//            Collection<GrantedAuthority> authorities = new ArrayList<>();
//            // 演示：【授权： 给该用户，哪些功能（接口）进行授权，】
//            // 当用户，登录后，访问 ：http://localhost:8080/user/save
//            // 有权限：会现在该接口的返回信息，没有权限，会进入对应的过滤器，显示：没有权限
//            // -----  手动添加 该用户的权限  -  该代码写死  -------------
//            authorities.add(() -> "LIST");
////            authorities.add(() -> "ADD");
//            return new org.springframework.security.core.userdetails.User(
//                    user.getUsername(),
//                    user.getPassword(),
//                    user.getEnabled(),     // 是否启用
//                    true, // 用户账号是否过期
//                    true,                  // 用户凭证是否过期
//                    true,                  // 用户是否未被锁定
//                    authorities);          // 权限列表

            // 2.用户角色资源配置
            // 演示：【授权： 给该用户，配置角色，哪些功能（接口）进行授权，】
            // 当用户，登录后，访问 ：http://localhost:8080/user/save
            // 有权限：会现在该接口的返回信息，没有权限，会进入对应的过滤器，显示：没有权限
//            return org.springframework.security.core.userdetails.User
//                    .withUsername(user.getUsername())
//                    .password(user.getPassword())
//                    .disabled(!user.getEnabled())  // 是否被禁用
//                    .credentialsExpired(false)     // 是否过期， false：未过期
//                    .accountLocked(false)          // 是否锁定， false：没有锁定
//                    .roles("ADMIN2")               // 角色 - 有权限 - 正常访问接口
////                    .roles("ADMIN222")           // 角色  - 没有授权的角色就是403
//                    .build();

            // 3.基于方法的授权
            // 演示：【授权： 给该用户，配置角色，哪些功能（接口）进行授权，】
            // 具体的配置，根据每个 各自的请求，注解实现
            // 当用户，登录后，访问 ：http://localhost:8080/user/save
            // 有权限：会现在该接口的返回信息，没有权限，会进入对应的过滤器，显示：没有权限
            return org.springframework.security.core.userdetails.User
                    .withUsername(user.getUsername())
                    .password(user.getPassword())
                    .disabled(!user.getEnabled())  // 是否被禁用
                    .credentialsExpired(false)     // 是否过期， false：未过期
                    .accountLocked(false)          // 是否锁定， false：没有锁定
                    .roles("ADMIN")                // 角色配置
                    .authorities("USER_ADD", "USER_UPDATE")  // 权限资源，一但配置，上面的 roles 角色，会失效
                    .build();
//                    .authorities("USER_ADD", "USER_UPDATE")  // 权限资源，一但配置，上面的 roles 角色，会失效

            // 演示：
            // 需要配合 UserController 接口权限注解 @PreAuthorize 的配置：
            // 1. 只配置 - 角色配置    .roles("ADMIN")
            //    登录：http://localhost:8080/login   yan用户进行登录
            //    访问：http://localhost:8080/user/save  （沒有权限）
            //    访问：http://localhost:8080/user/list  （沒有权限） - 因为用户名不是admin
            // 使用  admin用户进行登录
            //    访问：http://localhost:8080/user/save  （沒有权限）
            //    访问：http://localhost:8080/user/list  （有权限访问）
            // 2. 配置 权限资源  .authorities("USER_ADD", "USER_UPDATE")
            //    登录：http://localhost:8080/login   yan用户进行登录
            //    访问：http://localhost:8080/user/save  （有权限）  - 因为配置了权限资源 USER_ADD
            //    访问：http://localhost:8080/user/list  （沒有权限） - 因为用户名不是admin
            // 使用  admin用户进行登录
            //    访问：http://localhost:8080/user/save  （有权限）  - 因为配置了权限资源 USER_ADD
            //    访问：http://localhost:8080/user/list  （沒有权限）- 因为配置了权限资源，角色配置会失效

        }
    }

    @Override
    public UserDetails updatePassword(UserDetails user, String newPassword) {
        return null;
    }

    // 创建用户
    @Override
    public void createUser(UserDetails userDetails) {
        User user = new User();
        user.setUsername(userDetails.getUsername());
        user.setPassword(userDetails.getPassword());
        user.setEnabled(true);
        userMapper.insert(user);
    }

    @Override
    public void updateUser(UserDetails user) {

    }

    @Override
    public void deleteUser(String username) {

    }

    @Override
    public void changePassword(String oldPassword, String newPassword) {

    }

    @Override
    public boolean userExists(String username) {
        return false;
    }

}
